﻿using NAudio.Wave;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Utilities
{
    public class NetworkUtils
    {
        static bool waiting = false;
        static AutoResetEvent  stop = new AutoResetEvent(false);
        static int bytesToRead = 10000;

        public static void DownloadFile(Uri url, string path)
        {
            WebClient webClient = new WebClient();
            string filename = GetFileNameFromUri(url);
            if(filename!="")
                webClient.DownloadFile(url, path);
        }
        public static bool IsFileName(string path)
        {
            string[] div = path.Split('.');
            if (div.Length == 2)
                return true;
            return false;
        }
        public static string GetFileNameFromUri(Uri url)
        {
            string[] segments = url.Segments;
            string filename = segments[segments.Length - 1];
            if (IsFileName(filename))
                return filename;
            return "";
        }
        public static Stream GetResponse(string url)
        {
            Debug.WriteLine("Starting get response from " + url);
            HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
            myReq.KeepAlive = false;
            try
            {
                HttpWebResponse resp = (HttpWebResponse)myReq.GetResponse();
                return resp.GetResponseStream();
            }
            catch (IOException ex)
            {
                Debug.WriteLine(ex.Message);
                return null;
            }
        }
        public static void PlayMp3FromUrl(Stream stream)
        {
            using (Stream ms = new MemoryStream())
            {
                byte[] buffer = new byte[bytesToRead];
                int read;
                while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }

                ms.Position = 0;
                using (WaveStream blockAlignedStream =
                    new BlockAlignReductionStream(
                        WaveFormatConversionStream.CreatePcmStream(
                            new Mp3FileReader(ms))))
                {
                    using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
                    {
                        waveOut.Init(blockAlignedStream);
                        waveOut.PlaybackStopped += (sender, e) =>
                        {
                            waveOut.Stop();
                        };

                        waveOut.Play();
                        waiting = true;
                        stop.WaitOne(10000);
                        waiting = false;
                    }
                }
            }
        }
        public static void PlayTTS(string text)
        {
            Stream ms = new MemoryStream();
            string query = String.Format("http://www.vnspeak.com/speakit.php?txt={0}", WebUtility.UrlEncode(text));
            var playThread = new Thread(() => PlayMp3FromUrl(GetResponse("http://translate.google.com/translate_tts?q=" + WebUtility.UrlEncode(text))));
            playThread.IsBackground = true;
            playThread.Start();
        }
        public static List<SearchType> BingSearch(string query)
        {
            // our appid from bing - 3F4313687C37F1....23A79E181D0A25
            const string urlTemplate = @"http://api.search.live.net/json.aspx?AppId=3F4313687C37F1...23A79E181D0A25&Market=en-US&Sources=Web&Adult=Strict&Query={0}&Web.Count=50";
            const string offsetTemplate = "&Web.Offset={1}";
            var resultsList = new List<SearchType>();
            int[] offsets = { 0, 50, 100, 150 };
            Uri searchUrl;
            foreach (var offset in offsets)
            {
                if (offset == 0)
                    searchUrl = new Uri(string.Format(urlTemplate, query));
                else
                    searchUrl = new Uri(string.Format(urlTemplate + offsetTemplate, query, offset));

                var page = new WebClient().DownloadString(searchUrl);
                var o = (JObject)JsonConvert.DeserializeObject(page);

                var resultsQuery =
                  from result in o["SearchResponse"]["Web"]["Results"].Children()
                  select new SearchType
                  {
                      url = result.Value<string>("Url").ToString(),
                      title = result.Value<string>("Title").ToString(),
                      content = result.Value<string>("Description").ToString(),
                      engine = SearchType.FindingEngine.Bing
                  };

                resultsList.AddRange(resultsQuery);
            }
            return resultsList;
        }
        public static List<SearchType> GoogleSearch(string query)
        {
            const string urlTemplate = @"http://ajax.googleapis.com/ajax/services/search/web?v=1.0&rsz=large&safe=active&q={0}&start={1}";
            var resultsList = new List<SearchType>();
            int[] offsets = { 0, 8, 16, 24, 32, 40, 48 };
            foreach (var offset in offsets)
            {
                var searchUrl = new Uri(string.Format(urlTemplate,WebUtility.HtmlEncode(query), offset));
                var page = new WebClient().DownloadString(searchUrl);
                var o = (JObject)JsonConvert.DeserializeObject(page);

                var resultsQuery =
                  from result in o["responseData"]["results"].Children()
                  select new SearchType
                  {
                      url = result.Value<string>("url").ToString(),
                      title = result.Value<string>("title").ToString(),
                      content = result.Value<string>("content").ToString(),
                      engine = SearchType.FindingEngine.Google
                  };

                resultsList.AddRange(resultsQuery);
            }
            return resultsList;
        }
    }
    public struct SearchType
    {
        public string url;
        public string title;
        public string content;
        public FindingEngine engine;
        public enum FindingEngine { Google, Bing, GoogleAndBing };
    }
}